package com.jxw.test.application.base.apiversion;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.condition.RequestCondition;

import javax.servlet.http.HttpServletRequest;

/**
 * 多版本的请求条件
 */
public class ApiVersionRequestCondition implements RequestCondition<ApiVersionRequestCondition> {

    /**
     * 当前的版本号
     */
    private double version;

    /**
     * 请求的version
     */
    private final String VERSION_NAME = "version";

    public double getVersion() {
        return version;
    }

    /**
     * 构造方法 - 传入版本号
     * @param version
     */
    public ApiVersionRequestCondition(double version){
        this.version = version;
    }

    /**
     * 当类上的条件和方法上条件同时存在时该如何处理
     * @param method
     * @return
     */
    @Override
    public ApiVersionRequestCondition combine(ApiVersionRequestCondition method) {
        //this 代表Controller的请求条件
        //method 代表Controller中某个方法的请求条件
        return method;
    }

    /**
     * 根据请求 返回符合条件的RequestCondition对象，如果没有则返回null
     * @param request
     * @return
     */
    @Override
    public ApiVersionRequestCondition getMatchingCondition(HttpServletRequest request) {
        double reqVersion = 1.0;
        //获取请求的版本号
        String apiVersion = request.getHeader(VERSION_NAME);
        if (StringUtils.isEmpty(apiVersion)) {
            apiVersion = request.getParameter(VERSION_NAME);
        }

        //赋予默认值
        if (!StringUtils.isEmpty(apiVersion)) {
            reqVersion = Math.max(Double.valueOf(apiVersion), 1.0);
        }

        if (this.version <= reqVersion) {
            return this;
        }
        return null;
    }

    /**
     * 排序 - 为了选择最优的请求条件对象
     * 返回版本号相对较大的那个方法
     * @param other
     * @param request
     * @return
     */
    @Override
    public int compareTo(ApiVersionRequestCondition other, HttpServletRequest request) {
        return Double.compare(other.getVersion(), this.getVersion());
    }
}
